/////////////////////////////////////////////////////////////////////////////
// Name:        wxmudtextctrl.cpp
// Purpose:     
// Author:      Stephen Whittle
// Modified by: 
// Created:     09/06/2009 08:55:53
// RCS-ID:      
// Copyright:   
// Licence:     
/////////////////////////////////////////////////////////////////////////////

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

////@begin includes
////@end includes
#include "globals.h"
#include "wxmudtextctrl.h"
#include <wx/tokenzr.h>
#include "wxmudcommandline.h"

////@begin XPM images
////@end XPM images


/*
 * wxMudTextCtrl type definition
 */

IMPLEMENT_DYNAMIC_CLASS( wxMudTextCtrl, wxTextCtrl )


/*
 * wxMudTextCtrl event table definition
 */

BEGIN_EVENT_TABLE( wxMudTextCtrl, wxTextCtrl )

////@begin wxMudTextCtrl event table entries
////@end wxMudTextCtrl event table entries
   // EVT_TEXT(wxID_ANY,wxAuiPanel::OnTextUpdateEvent);
   //wxkeyevent
END_EVENT_TABLE()


/*
 * wxMudTextCtrl constructors
 */

wxMudTextCtrl::wxMudTextCtrl()
{
    Init();
}

wxMudTextCtrl::wxMudTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
    Init();
    Create(parent, id, value, pos, size, style | wxTE_RICH2 | wxTE_READONLY | wxTE_AUTO_URL, validator);
    //Create(parent, id, value, pos, size, style | wxTE_RICH2 | wxTE_AUTO_URL, validator);

    this->windowName = wxT("Tab");
}


/*
 * wxMudTextCtrl creator
 */

bool wxMudTextCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator)
{
////@begin wxMudTextCtrl creation
    wxTextCtrl::Create(parent, id, value, pos, size, style, validator);
    CreateControls();
////@end wxMudTextCtrl creation

    return true;
}


/*
 * wxMudTextCtrl destructor
 */

wxMudTextCtrl::~wxMudTextCtrl()
{
////@begin wxMudTextCtrl destruction
////@end wxMudTextCtrl destruction
mudTextWindows.Remove(this);
}


/*
 * Member initialisation
 */

void wxMudTextCtrl::Init()
{
////@begin wxMudTextCtrl member initialisation
////@end wxMudTextCtrl member initialisation
}


/*
 * Control creation for wxMudTextCtrl
 */

void wxMudTextCtrl::CreateControls()
{    
////@begin wxMudTextCtrl content construction
////@end wxMudTextCtrl content construction
wxTextAttr defaultStyle(wxColour(pConfig->Read(wxT("/Colours/DefaultText"),wxT("rgb(255, 255, 255)"))));
this->SetDefaultStyle(defaultStyle); 
    //actually what I should be doing is connecting evt_char to wxMudCommandLine::Keypress,NULL, commandLine
    //this->Connect(wxID_ANY, wxEVT_CHAR, wxKeyEventHandler(wxMudCommandLine::OnChar), NULL, commandLine);
    this->Connect(wxID_ANY, wxEVT_CHAR, wxKeyEventHandler(wxMudTextCtrl::OnChar), NULL, this);
    this->Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxMudTextCtrl::OnKey), NULL, this);
    this->Connect(wxID_ANY, wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler(wxMudCommandLine::OnTextEnter), NULL, commandLine);
    commandLineLocal = commandLine;
}

void wxMudTextCtrl::ProcessText( wxString s){
//should potentially rejoin the strings after taking everything out and then process it in the window
    bool textFound = false;
    s.Replace(wxT("[m"),wxT("[0m"));
    //wxChar cr = (wxChar)0x0d;
    //s.Replace(&cr, wxEmptyString);
	int i  = s.find('\e');
    //wxMessageBox(wxT("test"));
    if (i == wxNOT_FOUND){
        i = s.find((wxChar)0x1b);
    }
	if (i != wxNOT_FOUND){
    //was 0,i
        wxString textToAppend = s.Mid(0,i);        
        if (textToAppend.IsEmpty() == false){
            wxStringTokenizer tkz(textToAppend, wxT('\n'),wxTOKEN_RET_DELIMS);
            while ( tkz.HasMoreTokens() ){
                wxString token = tkz.GetNextToken();

                //if pConfig->Write(wxT("/UI/ShowGauges")
                //CheckForGaugeString(token);



                if ((this->filterList).GetCount()){
                    int i = 0;
                    while ((i < (this->filterList).GetCount()) && (!textFound)){
                        if (token.Find(filterList[i]) == wxNOT_FOUND){
                            i++;
                        }else{
                            textFound = true;
                            token = token  +wxT('\n');
                            i++;
                        }
                    }
                }else {
                    textFound = true;
                
                }
                //in here should go filter checking
                if (textFound){
                    this->Freeze();
                    
                    //this should only print the line containing the filter text
                    this->AppendText( token);
                    this->ScrollLines(2);
                    this->ShowPosition( this->GetLastPosition() ); // Ensure the last line is shown at the very bottom of the window
                    this->Thaw();
                }
                // process token here
            }
            
            
            
            //this->AppendText(textToAppend);
              }
            i++;
            //this is where the parser isnt going right
            //need to set some sort of flag to indicate we are still parsing a code
            
            wxString s2 = s.Mid(i+1);
            int j = s2.find('m');
            /*
            //something like:
            if (j == wxNOT_FOUND){
            possibly we havent reached the end of the code
            need to call a function to buffer the bit that could potentially be a code
            well ive already looked for the \e so we should be sure at this point that theres a code behind the [
            we should just post the bit back maybe, turn processtext into a wxString returning the bit to append to the next run through or something
            actually could create a global 'unprocessed' wxString and dump it in there
            then in the network code check and append it before calling processtexts
            
            }
            */
            wxString codes = s2.Mid(0,j);
            parseAndSetColours(codes);
            ProcessText(s2.Mid(j+1));
       
    }else{
        //this->GetSize().GetHeight()
        // Dance...
        wxStringTokenizer tkz(s, wxT('\n'),wxTOKEN_RET_DELIMS);
        while ( tkz.HasMoreTokens() )
        {
            wxString token = tkz.GetNextToken();
            if ((this->filterList).GetCount()){
                int i = 0;
                while ((i < (this->filterList).GetCount()) && (!textFound)){
                    if (token.Find(filterList[i]) == wxNOT_FOUND){
                        i++;
                    }else{
                        textFound = true;
                        token = token +wxT('\n');
                        i++;
                    }
                }

            }else {
                    textFound = true;
                
            }
            
            //in here should go filter checking
            if(textFound){
            
            //in here should go any sort of scripting stuff
            this->Freeze();
            this->AppendText( token );
            wxLogDebug(token);
            this->ScrollLines(2);
            this->ShowPosition( this->GetLastPosition() +1 ); // Ensure the last line is shown at the very bottom of the window //didnt have +1
            this->Thaw();
            }
            // process token here
        }
        // Add the text
    }
}
void wxMudTextCtrl::parseAndSetColours(wxString codes){
    wxLogDebug(codes);
    wxStringTokenizer colourTokens(codes, wxT(";"),wxTOKEN_STRTOK );
    bool bright = false;
    wxTextAttr * fgColour = new wxTextAttr;
    while ( colourTokens.HasMoreTokens() ){
        wxString token = colourTokens.GetNextToken();
        long* longToken = new long;
        token.ToLong(longToken);
        switch ( *longToken ) {
            case 0 : 
                bright = false;
                this->SetDefaultStyle(wxTextAttr(wxColour(255,255,255),wxColour(0,0,0)));
                break;
            case 1:
                bright = true;
                break;
            case 30 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(0,0,0));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 31 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(187,0,0));
                this->SetDefaultStyle(*fgColour);
                break;
            case 32 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(0,187,0));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 33 : 
                if (bright){
                    *fgColour = this->GetDefaultStyle();
                    fgColour->SetTextColour(wxColour(221,221,0));
                    this->SetDefaultStyle(*fgColour);
                    break;
                }
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(255,187,0));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 34 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(0,0,187));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 35 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(159,0,159));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 36 : 
               *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(0,187,187));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 37 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(255,255,255));
                this->SetDefaultStyle(*fgColour);
                
                break;
            case 39 : 
                //eventually to get defaults from user configuration
                *fgColour = this->GetDefaultStyle();
                fgColour->SetTextColour(wxColour(255,255,255));
                this->SetDefaultStyle(*fgColour);
                break;
            case 41 : 
                
                *fgColour = this->GetDefaultStyle();
                fgColour->SetBackgroundColour(wxColour(187,0,0));
                this->SetDefaultStyle(*fgColour);
                break;
            case 42 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetBackgroundColour(wxColour(0,187,0));
                this->SetDefaultStyle(*fgColour);
                break;
            case 43 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetBackgroundColour(wxColour(221,221,0));
                this->SetDefaultStyle(*fgColour);
                break;
            case 44 : 
                *fgColour = this->GetDefaultStyle();
                fgColour->SetBackgroundColour(wxColour(0,0,187));
                this->SetDefaultStyle(*fgColour);
                break;
/*
            NB [m is apparently an alias for [0m - this will not be implemented at this point in time.
            [0m	 reset; clears all colors and styles (to white on black)
            [1m	 bold on (see below)
            [3m	italics on
            [4m	underline on
            [7m	inverse on; reverses foreground & background colors
            [9m	strikethrough on
            [22m bold off (see below)
            [23m italics off
            [24m underline off
            [27m inverse off
            [29m strikethrough off
            [30m set foreground color to black
            [31m set foreground color to red
            [32m set foreground color to green
            [33m set foreground color to yellow
            [34m set foreground color to blue
            [35m set foreground color to magenta (purple)
            [36m set foreground color to cyan
            [37m set foreground color to white
            [39m set foreground color to default (white)
            [40m set background color to black
            [41m set background color to red
            [42m set background color to green
            [43m set background color to yellow
            [44m set background color to blue
            [45m set background color to magenta (purple)
            [46m set background color to cyan
            [47m set background color to white
            [49m set background color to default (black)
  */
                default :
                break;
        }

    }
    // process token here, use a switch
}


/*!
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON
 */

int wxMudTextCtrl::GetLinesPerPage(void){

//wxTextAttr * style = new wxTextAttr;

//style = this->GetDefaultStyle();
//style->GetFont().GetPixelSize();

return 0;
}

void wxMudTextCtrl::CheckForGaugeString(wxString checkme){
pConfig->Read(wxT("/UI/GaugeString"));

}


void wxMudTextCtrl::OnChar( wxKeyEvent& event )
{
        
            commandLineLocal->ChangeValue(event.GetUnicodeKey());
            commandLineLocal->SetInsertionPointEnd();
            commandLineLocal->SetFocus();
            //event.Skip();
}

void wxMudTextCtrl::OnKey( wxKeyEvent& event )
{
    switch(event.GetUnicodeKey()){
        case 8: //backspace
            //commandLine->AddPendingEvent(event);
            commandLineLocal->SetValue((commandLine->GetValue()).RemoveLast());
            commandLineLocal->SetInsertionPointEnd();
            commandLineLocal->SetFocus();
            break;
        case 13: //enter
            //This needs fixing
            { wxCommandEvent* newEvent = new wxCommandEvent(wxEVT_COMMAND_TEXT_ENTER);
            commandLineLocal->OnTextEnter(*newEvent);
            commandLineLocal->SetFocus();
            }
            break;
        case 37: //LEFT
            commandLineLocal->SetInsertionPoint(commandLine->GetLastPosition() -1);
            commandLineLocal->SetFocus();
            break;
        case 38: //UP
            commandLineLocal->OnInputKeyDown( event );
            commandLineLocal->SetInsertionPoint(commandLine->GetLastPosition());
            commandLineLocal->SetFocus();
            break;
        case 39: //RIGHT
            commandLineLocal->SetInsertionPoint(commandLine->GetLastPosition());
            commandLineLocal->SetFocus();
            break;
        case 40: //DOWN
            commandLineLocal->OnInputKeyDown( event );
            commandLineLocal->SetInsertionPointEnd();
            commandLineLocal->SetFocus();
            break;
        case 46: //delete
//            commandLine->SetInsertionPointEnd();
            
            commandLineLocal->SetFocus();
            commandLineLocal->OnInputKeyDown(event);
            break;
        default:
            event.Skip();
        
    }

}

